package br.com.it4.framework.view.datamodel;

import java.io.Serializable;
import java.util.List;

import javax.faces.model.DataModel;

/**
 * Entidade modelo para os dados utilizados em componentes de paginação.
 * 
 * @author Mozart Silva (mozart.vsilva@gmail.com)
 * 
 * @param <T>
 *            O tipo da lista de registros a ser exibida na paginação.
 */
@SuppressWarnings("rawtypes")
public class PagedListDataModel<T> extends DataModel implements Serializable {

    /** Indice de controle da linha dos registros. */
    private int rowIndex = -1;

    /** Número total de registros. */
    private int rowCount;

    /** Número de registros por página. */
    private int pageSize;

    /** Número de páginas. */
    private int pageCount;
    
    /** A página atual. */
    private int currentPage;

    /** Registros a serem exibidos. */
    private List<T> list;

    /**
     * Construtor padrão.
     */
    public PagedListDataModel() {
        super();
    }

    /**
     * Construtor alternativo.
     * 
     * @param list
     *            A lista de registros a serem exibidos.
     * @param rowCount
     *            Número de registros total.
     * @param pageSize
     *            Número de registros por página.
     */
    public PagedListDataModel(List<T> list, int rowCount, int pageSize) {
        super();
        setWrappedData(list);
        this.rowCount = rowCount;
        this.pageSize = pageSize;
    }

    /** {@inheritDoc} */
    public boolean isRowAvailable() {
        boolean isRowAvailable = false;

        if (list != null) {
            int rowIndex = getRowIndex();

            if (rowIndex >= 0 && rowIndex < list.size()) {
                isRowAvailable = true;
            }
        }

        return isRowAvailable;
    }

    /** {@inheritDoc} */
    public int getRowCount() {
        return rowCount;
    }
    
    /**
     * @param rowCount the rowCount to set
     */
    public void setRowCount(int rowCount) {
        this.rowCount = rowCount;
    }

    /** {@inheritDoc} */
    public Object getRowData() {
        Object rowData = null;

        if (list != null) {
            if (!isRowAvailable()) {
                throw new IllegalArgumentException();
            } else {
                int dataIndex = getRowIndex();
                rowData = list.get(dataIndex);
            }
        }

        return rowData;
    }

    /** {@inheritDoc} */
    public int getRowIndex() {
        return (rowIndex % pageSize);
    }

    /** {@inheritDoc} */
    public void setRowIndex(int rowIndex) {
        this.rowIndex = rowIndex;
    }

    /** {@inheritDoc} */
    public Object getWrappedData() {
        return list;
    }

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    public void setWrappedData(Object list) {
        this.list = (List) list;
    }

    /**
     * @return O pageCount a ser recuperado.
     */
    public int getPageCount() {
        pageCount = this.rowCount / this.pageSize;
        if ((this.rowCount % this.pageSize) != 0) {
            pageCount = pageCount + 1;
        }
        return pageCount;
    }

    /**
     * @return O pageSize a ser recuperado.
     */
    public int getPageSize() {
        return pageSize;
    }

    /**
     * @param pageSize
     *            O pageSize a ser atribuido.
     */
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    /**
     * @return O currentPage a ser recuperado.
     */
    public int getCurrentPage() {
        return currentPage;
    }

    /**
     * @param currentPage
     *            O currentPage a ser atribuido.
     */
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    
}